/**
 * 性能监控和优化工具
 */

interface PerformanceMetrics {
  fcp?: number; // First Contentful Paint
  lcp?: number; // Largest Contentful Paint
  fid?: number; // First Input Delay
  cls?: number; // Cumulative Layout Shift
  ttfb?: number; // Time to First Byte
  loadTime?: number; // 页面加载总时间
}

interface ResourceTiming {
  name: string;
  duration: number;
  size: number;
  type: string;
}

class PerformanceMonitor {
  private metrics: PerformanceMetrics = {};
  private observers: PerformanceObserver[] = [];

  constructor() {
    this.init();
  }

  private init() {
    // 标记应用开始时间
    if (typeof window !== 'undefined' && window.performance) {
      window.performance.mark('app-init-start');
    }

    this.setupObservers();
  }

  private setupObservers() {
    // 监听 First Contentful Paint
    this.observePerformanceEntry(['paint'], (entries) => {
      const fcpEntry = entries.find(entry => entry.name === 'first-contentful-paint');
      if (fcpEntry) {
        this.metrics.fcp = fcpEntry.startTime;
        this.logMetric('FCP', fcpEntry.startTime);
      }
    });

    // 监听 Largest Contentful Paint
    this.observePerformanceEntry(['largest-contentful-paint'], (entries) => {
      const lcpEntry = entries[entries.length - 1]; // 取最后一个值
      if (lcpEntry) {
        this.metrics.lcp = lcpEntry.startTime;
        this.logMetric('LCP', lcpEntry.startTime);
      }
    });

    // 监听 First Input Delay
    this.observePerformanceEntry(['first-input'], (entries) => {
      const fidEntry = entries[entries.length - 1];
      if (fidEntry) {
        this.metrics.fid = (fidEntry as any).processingStart - fidEntry.startTime;
        this.logMetric('FID', this.metrics.fid);
      }
    });

    // 监听 Cumulative Layout Shift
    this.observePerformanceEntry(['layout-shift'], (entries) => {
      let clsValue = 0;
      entries.forEach((entry) => {
        if (!(entry as any).hadRecentInput) {
          clsValue += (entry as any).value;
        }
      });
      this.metrics.cls = clsValue;
      this.logMetric('CLS', clsValue);
    });
  }

  private observePerformanceEntry(entryTypes: string[], callback: (entries: any[]) => void) {
    try {
      const observer = new PerformanceObserver((list) => {
        callback(list.getEntries());
      });
      observer.observe({ entryTypes });
      this.observers.push(observer);
    } catch (error) {
      console.warn(`Performance observer for ${entryTypes} not supported:`, error);
    }
  }

  private logMetric(name: string, value: number) {
    console.log(`🔍 ${name}: ${value.toFixed(2)}${this.getMetricUnit(name)}`);
  }

  private getMetricUnit(metric: string): string {
    switch (metric) {
      case 'CLS':
        return '';
      case 'TTFB':
      case 'FCP':
      case 'LCP':
      case 'FID':
        return 'ms';
      default:
        return 'ms';
    }
  }

  // 计算Time to First Byte
  public calculateTTFB(): number {
    if (typeof window === 'undefined' || !window.performance || !window.performance.timing) {
      return 0;
    }

    const timing = window.performance.timing;
    const ttfb = timing.responseStart - timing.navigationStart;
    this.metrics.ttfb = ttfb;
    this.logMetric('TTFB', ttfb);
    return ttfb;
  }

  // 计算页面加载时间
  public calculateLoadTime(): number {
    if (typeof window === 'undefined' || !window.performance || !window.performance.timing) {
      return 0;
    }

    const timing = window.performance.timing;
    const loadTime = timing.loadEventEnd - timing.navigationStart;
    this.metrics.loadTime = loadTime;
    this.logMetric('Load Time', loadTime);
    return loadTime;
  }

  // 获取资源加载信息
  public getResourceTimings(): ResourceTiming[] {
    if (typeof window === 'undefined' || !window.performance || !window.performance.getEntriesByType) {
      return [];
    }

    const resources = window.performance.getEntriesByType('resource') as PerformanceResourceTiming[];
    return resources
      .filter(resource => resource.name.includes('.js') || resource.name.includes('.css'))
      .map(resource => ({
        name: resource.name.split('/').pop() || resource.name,
        duration: resource.duration,
        size: resource.transferSize || 0,
        type: this.getResourceType(resource.name)
      }))
      .filter(resource => resource.duration > 100) // 只显示加载时间超过100ms的资源
      .sort((a, b) => b.duration - a.duration);
  }

  private getResourceType(name: string): string {
    if (name.endsWith('.js')) return 'JavaScript';
    if (name.endsWith('.css')) return 'CSS';
    if (name.includes('.woff') || name.includes('.ttf')) return 'Font';
    if (name.match(/\.(png|jpg|jpeg|gif|webp|svg)$/)) return 'Image';
    return 'Other';
  }

  // 获取完整的性能报告
  public getPerformanceReport(): PerformanceMetrics & { resources: ResourceTiming[] } {
    this.calculateTTFB();
    this.calculateLoadTime();
    const resources = this.getResourceTimings();

    return {
      ...this.metrics,
      resources
    };
  }

  // 打印性能报告
  public printPerformanceReport() {
    console.group('🚀 性能监控报告');

    const report = this.getPerformanceReport();

    console.log('核心性能指标:');
    console.table(report);

    if (report.resources.length > 0) {
      console.log('资源加载时间 (超过100ms):');
      console.table(report.resources.slice(0, 10)); // 只显示前10个最慢的资源
    }

    // 性能建议
    this.generatePerformanceSuggestions(report);

    console.groupEnd();
  }

  private generatePerformanceSuggestions(report: PerformanceMetrics & { resources: ResourceTiming[] }) {
    console.log('💡 性能优化建议:');

    if (report.fcp && report.fcp > 1800) {
      console.log('⚠️  FCP过长 (>1.8s)，建议：优化关键资源、使用CDN、减少首屏内容');
    }

    if (report.lcp && report.lcp > 2500) {
      console.log('⚠️  LCP过长 (>2.5s)，建议：优化图片、预加载关键资源');
    }

    if (report.fid && report.fid > 100) {
      console.log('⚠️  FID过长 (>100ms)，建议：减少JavaScript执行时间、优化主线程');
    }

    if (report.cls && report.cls > 0.1) {
      console.log('⚠️  CLS过高 (>0.1)，建议：为图片设置尺寸、避免插入内容');
    }

    if (report.ttfb && report.ttfb > 800) {
      console.log('⚠️  TTFB过长 (>800ms)，建议：优化服务器响应、使用CDN');
    }

    if (report.resources.some(r => r.duration > 1000)) {
      console.log('⚠️  存在加载时间超过1秒的资源，建议：优化或拆分大文件');
    }
  }

  // 清理观察者
  public disconnect() {
    this.observers.forEach(observer => observer.disconnect());
    this.observers = [];
  }

  // 标记性能点
  public mark(markName: string) {
    if (typeof window !== 'undefined' && window.performance && window.performance.mark) {
      window.performance.mark(markName);
    }
  }

  // 测量两个标记之间的时间
  public measure(measureName: string, startMark: string, endMark: string) {
    if (typeof window !== 'undefined' && window.performance && window.performance.measure) {
      window.performance.measure(measureName, startMark, endMark);
      const measure = window.performance.getEntriesByName(measureName, 'measure')[0];
      if (measure) {
        console.log(`⏱️  ${measureName}: ${measure.duration.toFixed(2)}ms`);
      }
    }
  }
}

// 创建单例
let performanceMonitor: PerformanceMonitor | null = null;

export function usePerformanceMonitor(): PerformanceMonitor {
  if (!performanceMonitor) {
    performanceMonitor = new PerformanceMonitor();
  }
  return performanceMonitor;
}

export { PerformanceMonitor };

// 导出类型
export type { PerformanceMetrics, ResourceTiming };
